/*
 * CharacterModel.h
 *
 *  Created on: 20.10.2012
 *      Author: caffeine
 */

#ifndef CHARACTERMODEL_H_
#define CHARACTERMODEL_H_

#include <object/AnimattedModelObject.h>
#include "BodyPart.h"
#include "../CharacterPattern.h"
#include "../CharacterSets.h"
#include <log/Log.h>
#include <image/ImageControlerRecord.h>
#include <image/CompositeImage.h>
#include <image/ImageLayout.h>
#include <animation/IAnimation.h>
#include <animation/IAnimationRecord.h>


class CharacterModel:public irr::object::AnimattedModelObject{
private:
	//irr::scene::ISceneNode*node;
	irr::scene::IAnimatedMeshSceneNode*node;
	BodyPart*body;
	BodyPart*feet;
	BodyPart*hands;
	BodyPart*lags;
	BodyPart*adds;

	irr::u32 facial;
	irr::u32 hair;
	irr::u32 hair_head;
	irr::u32 skin;
	irr::u32 face;
	irr::u32 bodyIndex;
	irr::u32 feetIndex;
	irr::u32 handsIndex;
	irr::u32 lagsIndex;
	irr::u32 addsIndex;

	CompositeImage*image;

	ImageLayout*skin_layout;
	ImageLayout*facial_layout;
	ImageLayout*face_layout;
	ImageLayout*pants;
	ImageLayout*jacket;
	ImageLayout*boots;

	CharacterPattern*parent;

	irr::animation::IAnimation*animation_group;
	irr::animation::IAnimationRecord*animation;
public:
	void resetTexture(){
		body->getAnimationModel()->setMaterialTexture(0,image->getTexture());
		feet->getAnimationModel()->setMaterialTexture(0,image->getTexture());
		hands->getAnimationModel()->setMaterialTexture(0,image->getTexture());
		lags->getAnimationModel()->setMaterialTexture(0,image->getTexture());
		adds->getAnimationModel()->setMaterialTexture(0,image->getTexture());

		body->getAnimationModel()->setMaterialFlag(irr::video::EMF_LIGHTING,false);
		feet->getAnimationModel()->setMaterialFlag(irr::video::EMF_LIGHTING,false);
		hands->getAnimationModel()->setMaterialFlag(irr::video::EMF_LIGHTING,false);
		lags->getAnimationModel()->setMaterialFlag(irr::video::EMF_LIGHTING,false);
		adds->getAnimationModel()->setMaterialFlag(irr::video::EMF_LIGHTING,false);
	}
protected:
	void resetAnimationForAllModel();
	void resetAnimationGroupForAllModel();

	virtual void on_model_load(irr::scene::ISceneNode*parent){
		MARKER;
		body->on_model_load(parent);
		feet->on_model_load(parent);
		hands->on_model_load(parent);
		lags->on_model_load(parent);
		adds->on_model_load(parent);
		irr::scene::ISceneNodeAnimator*joint_updater=getDevice()->getSceneManager()->createJoinUpdaterAnimator(true);
		resetTexture();

/*
		body->getAnimationModel()->setTransitionTime(0.5);
		feet->getAnimationModel()->setTransitionTime(0.5);
		hands->getAnimationModel()->setTransitionTime(0.5);
		lags->getAnimationModel()->setTransitionTime(0.5);
		adds->getAnimationModel()->setTransitionTime(0.5);
		*/

		body->getAnimationModel()->setJointMode(irr::scene::EJUOR_CONTROL);
		feet->getAnimationModel()->setJointMode(irr::scene::EJUOR_CONTROL);
		hands->getAnimationModel()->setJointMode(irr::scene::EJUOR_CONTROL);
		lags->getAnimationModel()->setJointMode(irr::scene::EJUOR_CONTROL);
		adds->getAnimationModel()->setJointMode(irr::scene::EJUOR_CONTROL);

		body->getAnimationModel()->addAnimator(joint_updater);
		feet->getAnimationModel()->addAnimator(joint_updater);
		hands->getAnimationModel()->addAnimator(joint_updater);
		lags->getAnimationModel()->addAnimator(joint_updater);
		adds->getAnimationModel()->addAnimator(joint_updater);
		joint_updater->drop();

		resetAnimationGroupForAllModel();
		resetAnimationForAllModel();
	}
	virtual void on_model_unload(){
		//LOG("UNLOAD MODEL");
		adds->on_model_unload();
		lags->on_model_unload();
		hands->on_model_unload();
		body->on_model_unload();
		feet->on_model_unload();
		//node->remove();
	}

	virtual void on_setCurrentAnimation(irr::animation::IAnimationRecord*record){
		if (!record){
			LOGE("Animation not found!");
			return;
		}
		body->on_setCurrentAnimation(record);
		adds->on_setCurrentAnimation(record);
		lags->on_setCurrentAnimation(record);
		hands->on_setCurrentAnimation(record);
		feet->on_setCurrentAnimation(record);
	}
	virtual void on_setAnimationGroup(irr::animation::IAnimation*group){
		body->on_setAnimationGroup(group);
		adds->on_setAnimationGroup(group);
		lags->on_setAnimationGroup(group);
		hands->on_setAnimationGroup(group);
		feet->on_setAnimationGroup(group);
	}
public:
	irr::animation::IAnimation*getAnimationGroup();
	CharacterModel(irr::IrrlichtDevice*my_device):irr::ILoadableObject(my_device),irr::object::AnimattedModelObject(0,0,my_device){
		animation_group=0;
		animation=0;
		image=new CompositeImage(my_device,irr::core::dimension2du(512,512));
		body=new BodyPart(0,my_device);
		feet=new BodyPart(0,my_device);
		hands=new BodyPart(0,my_device);
		lags=new BodyPart(0,my_device);
		adds=new BodyPart(0,my_device);

		skin_layout=image->add(irr::core::position2di(0,0));
		face_layout=image->add(irr::core::position2di(0,320));
		facial_layout=image->add(irr::core::position2di(0,320));
		jacket=image->add(irr::core::position2di(256,0));
		pants=image->add(irr::core::position2di(256,192));
		boots=image->add(irr::core::position2di(256,320));
		//pants=image->add(irr::core::position2di(256,192));
	}

	~CharacterModel(){
		adds->drop();
		lags->drop();
		hands->drop();
		feet->drop();
		body->drop();
		image->drop();
	}

	void setVisual(CharacterSets cs);
	CharacterSets getVisual();

	void setLayoutTexture(int type,irr::io::path path);

	void setAnimation(irr::animation::IAnimationRecord*animation);
	void setAnimationGroup(irr::animation::IAnimation*group);

	static const int PANTS=1;
	static const int JACKET=2;
	static const int BOOTS=3;
};


#endif /* CHARACTERMODEL_H_ */
